<?php
declare (strict_types = 1);

namespace app\controller\backend;

use app\model\Attachment;
use app\model\AttachmentCate;
use app\model\Model;
use app\model\RecycleBin;
use app\model\SysSetting;
use app\service\ThemeService;
use app\service\upload\Upload;
use app\validate\AttachmentValidate;
use think\exception\ValidateException;
use think\facade\Db;
use think\file\UploadedFile;

class AttachmentController extends BaseController
{
    protected  $type = [
        'file'    => 4,
        'image'    => 2,
        'video'    => 3,
        'mp3'    => 5,
        'zip'   => 1,
    ];

    /**
     * 显示资源列表
     *
     * @return \think\response\Json
     * @throws \app\exception\ModelException
     */
    public function index(Attachment $attachment): \think\response\Json
    {
        $type = (int)input('type');
        $where = [
            ['seller_id' ,'=', $this->admin['seller_id']],
            ['is_del' ,'=', 1],
        ];
        $cate_id = (int)input('cate_id');
        if($cate_id){
            $Cate = new AttachmentCate();
            $cate = $Cate -> getCustomData(['id'=>$cate_id,'seller_id'=>$this->admin['seller_id']])['data'];
            $path = $cate['path'] . '-' . $cate['id'];
            $cates = $Cate -> getAllCustomData([['path','like',$path.'%'],['seller_id','=',$this->admin['seller_id']]])['data'];
            $ids = array_column($cates,'id');
            array_unshift($ids,$cate['id']);
            if(count($ids) == 1){
                array_push($where,['attachment_cate_id','=',$ids[0]]);
            }else{
                array_push($where,['attachment_cate_id','in',$ids]);
            }
        }
        if($type){
            array_push($where,['type','=',$type]);
        }
        $name = input('name');
        if(!empty($name)){
            array_push($where,['name','like','%'.$name.'%']);
        }
        $limit = $this->setLimit();
        $attachmentList = $attachment->getAttachmentList($where,$limit);
        return json(pageReturn($attachmentList));
    }

    /**
     * 保存新建的资源
     *
     * @return \think\response\Json
     */
    public function save(Attachment $attachment): \think\response\Json
    {
        if(request()->isPost()){
            $param = input('post.');
            foreach($param as &$val){
                try{
                    validate(AttachmentValidate::class)->scene('save')->check($val);
                    $val['seller_id'] = $this->admin['seller_id'];
                }catch (ValidateException $e){
                    return jsonReturn(-1, $e->getError());
                }
            }
            $res = $attachment->addAllCustomData($param);
            return json($res);
        }
        return jsonReturn(-3,'请求方法错误');
    }

    /**
     * 显示指定的资源
     *
     * @return \think\response\Json
     * @throws \app\exception\ModelException
     */
    public function read(Attachment $attachment): \think\response\Json
    {

        $id = (int)input('id');
        if(!$id){
            return jsonReturn(-1,'附件ID不能为空');
        }
        $where = [
            'id' => $id,
            'seller_id' => $this->admin['seller_id'],
            'is_del' => 1,
        ];
        $res = $attachment->getAttachment($where);
        return json($res);
    }

    /**
     * 保存更新的资源
     * @return \think\response\Json
     * @throws \app\exception\ModelException
     */
    public function update(Attachment $attachment): \think\response\Json
    {
        if(request()->isPost()){
            $param = input('post.');
            $seller_id = $this->admin['seller_id'];
            try {
                validate(AttachmentValidate::class)->scene('update')->check($param);
            } catch (ValidateException $e) {
                return jsonReturn(-1, $e->getError());
            }
            $where = [
                'id' => $param['id'],
                'seller_id' => $seller_id,
            ];
            $res = $attachment -> updateAttachment($where,$param);
            return json($res);
        }
        return jsonReturn(-3,'请求方法错误');
    }

    /**
     * 删除指定资源
     *
     * @throws \app\exception\ModelException
     */
    public function delete(Attachment $Attachment): \think\response\Json
    {
        $idArr = $this->request->param('id');
        if(is_string($idArr)){
            $ids = explode(',',$idArr);
        }else{
            $ids = [$idArr];
        }
        $where = [
            ['id','in',$ids],
            ['seller_id','=',$this->admin['seller_id']]
        ];
        $attachment = $Attachment -> getAllCustomData($where)['data'];
        Db::startTrans();
        try{
            $binData=[];
            foreach ($attachment as $val){
                // 复制删除内容到回收站表
                array_push($binData,[
                    'seller_id' => $this->admin['seller_id'],
                    'object_id' =>  $val['id'],
                    'sub_id' => 0,
                    'module_id' => 0,
                    'table_name' => '附件-attachment',
                    'title' => !empty($val['name']) ? $val['name'] : '附件' . $val['id'],
                    'admin_id' => $this->admin['uid'],
                    'name' => $this->admin['name'],
                ]);
            }
            $recycleBin = new RecycleBin();
            $recycleBin -> addAllCustomData($binData);
            $Attachment -> updateAttachment($where,['is_del'=>2,'delete_time'=>time()]);
            optEventLog($idArr,'附件删除','删除');
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            return jsonReturn(-1,'删除失败');
        }

        return jsonReturn(0,'删除成功');
    }

    /**
     * @throws \app\exception\ModelException
     */
    public function uploadAndSave(Attachment $attachment): \think\response\Json
    {
        if(request()->isPost()){
            set_time_limit(0);
            $file = request()->file('file');
            if(empty($file)){
                return jsonReturn(-8,'文件上传失败,请重新尝试');
            }
            $seller_id = $this->admin['seller_id'];
            // 查看文件类型
            $fileName = $file->getOriginalName();
            $fileExt = $file->getOriginalExtension();
            $file_type = fileFormat($fileName);
            $fileType = $this->type[$file_type];
            // 附件大小和类型验证
            // 获取上传配置
            $Settings = new SysSetting();
            $uploadSetting = $Settings->getAllCustomData(['parent_id'=>1,'group'=>'upload','status'=>1],'id desc','id,group,title,value')['data'];
            $uploadSetting = getColumnForKeyArray($uploadSetting,'title');
            $limitSize = $uploadSetting[$file_type.'_size']['value'] * 1024;     // byte
            $fileSize = $file->getSize();       // 单位byte
            if($fileSize > $limitSize){
                return jsonReturn(-1,'文件过大，请修改上传限制或者替换小的文件');
            }
            $extArr = explode(',',$uploadSetting[$file_type.'_ext']['value']);
            if(!in_array($fileExt,$extArr)){
                return jsonReturn(-2,'文件格式错误，请重新上传');
            }
            $type = $this->getUploadType();
            $upload = new Upload();
            $info = $upload->create($file,$seller_id, $type,$file_type);

            if ($info) {
                $res = $this->getResponse($fileType,$fileSize,$upload);
                return json($res);
            }
            return jsonReturn(-1, '上传失败请重新尝试');
        }
        return jsonReturn(-3,'请求方法错误');
    }


    public function sliceUploadAndSave(Upload $uploader): \think\response\Json
    {
        $params = $this->request->param();
        $params['resource_chunk'] = $this->request->file('resource_chunk');
        $file_type = fileFormat('abc.'.$params['resource_type']);
        $res = $uploader->tmpMove($params['resource_chunk'],$file_type,$params['resource_temp_path'],$params['chunk_index']);
        if($res){
            $tmPath = runtime_path() .  'slice/'.$file_type.'/'.$params['resource_temp_path'];
            $num = getFileNumber($tmPath);
            if($num == $params['chunk_total']){
                try {
                    $filepath = $uploader->mergeBlob($tmPath,$params['resource_temp_path'],$params['chunk_total'],$params['resource_type']);
                    $type = $this->getUploadType();
                    $file = new UploadedFile($filepath,$params['resource_temp_path'].'.'.$params['resource_type']);
                    if($type == 'local'){
                        if(!file_exists(public_path() . 'storage/' . $file_type.'/'. date('Ymd'))){
                            @mkdir(public_path() . 'storage/' . $file_type.'/'. date('Ymd'),0755,true);
                        }
                        copy($filepath,public_path() . 'storage/' . $file_type.'/'. date('Ymd') .'/'.$params['resource_temp_path'] .'.'.$params['resource_type']);
                        $cateId = (int)input('attachment_cate_id');
                        $uploadInfo['name'] = $params['resource_name'];
                        $uploadInfo['url'] = 'storage/' . $file_type.'/'. date('Ymd') .'/'.$params['resource_temp_path'] .'.'.$params['resource_type'];
                        $uploadInfo['mime_type'] = $params['resource_type'];
                        $uploadInfo['storage'] = 1;
                        $uploadInfo['type'] = $this->type[$file_type];
                        $uploadInfo['size'] = round($file->getSize() / 1024,2);
                        $uploadInfo['attachment_cate_id'] = $cateId;
                        $attachment = new Attachment();
                        $res = $attachment->addAttachment($uploadInfo);
                        optEventLog($res['data']['id'],'附件','添加');
                        (new ThemeService()) -> deleteFile($tmPath);
                        return json($res);
                    }else{
                        $upload = new Upload();
                        $res = $upload->create($file,$this->admin['seller_id'], $type);
                        if($res){
                            $fileSize = $file->getSize();
                            $fileType = $this->type[$file_type];
                            $res  = $this->getResponse($fileType,$fileSize,$upload);
                            (new ThemeService()) -> deleteFile($tmPath);
                            return json($res);
                        }else{
                            return jsonReturn(-1,'上传失败');
                        }
                    }
                } catch (\Exception $e) {
                    return jsonReturn(-1,$e->getMessage(),[]);
                }

            }else{
                return jsonReturn(1,'上传成功',$res);
            }
        }else{
            return jsonReturn(-1,'上传失败',$res);
        }
    }

    /**
     * @throws \app\exception\ModelException
     */
    public function getResponse($fileType, $fileSize, $upload)
    {
        $uploadInfo = $upload->getUploadFileInfo();
        $cateId = (int)input('attachment_cate_id');
        if ($uploadInfo['code'] == 0) {
            $uploadInfo['data']['type'] = $fileType;
            $uploadInfo['data']['size'] = round($fileSize / 1024,2);
            $uploadInfo['data']['attachment_cate_id'] = $cateId;
            $attachment = new Attachment();
            $res = $attachment->addAttachment($uploadInfo['data']);
            optEventLog($res['data']['id'],'附件','添加');
            return $res;
        } else {
            return $uploadInfo;
        }
    }

    public function getFileType()
    {

    }

    /**
     * @throws \app\exception\ModelException
     */
    public function getUploadType()
    {
        // 文件信息提取
        $where = [
            'seller_id' => $this->admin['seller_id'],
            'group' => 'upload',
            'title' => 'storage'
        ];
        $place = new SysSetting();
        return $place->getSysSetting($where)['data']->toArray()['value'];
    }

}
